# -*- coding: utf-8 -*-

import csv, codecs, cStringIO,  logging
logger = logging.getLogger('csvfile')
logger.setLevel(logging.DEBUG)

class UTF8Recoder:
  """
  Iterator that reads an encoded stream and reencodes the input to UTF-8. Lifted from the python docs.
  """
  def __init__(self, f, encoding):
    self.reader = codecs.getreader(encoding)(open(f))
    self.sample = self.reader.read(1024)
    self.reader.seek(0)

  def __iter__(self):
    return self

  def next(self):
    return self.reader.next().encode("utf-8")

class UnicodeCSVReader:
  """
  A CSV reader which will iterate over lines in the CSV file "f",
  which is encoded in the given encoding. Lifted from the python docs.
  """
  headers = []
  series_labels = []
  row_counter = -1
  def __init__(self, f, dialect=None, encoding="utf-8", **kwds):
    self.series_labels = []
    f = UTF8Recoder(f, encoding)
#    logger.debug("sample is: %s",  f.sample)
    snif = csv.Sniffer()
    if dialect is None:
      self.dialect = snif.sniff(f.sample)
    self.reader = csv.reader(f, dialect=dialect, **kwds)
    alphachars = sum( [ 1 for char in f.sample.split("\n")[0] if char.isalpha() ] )
    if alphachars > 2: # a columns line must at least have 2 alphachars
      self.headers = [ cell.value for cell in self.next() ]
    self.row_counter = -1

  def next(self):
    row = self.reader.next()
    logger.debug("row: %s / %s", row, repr(row))
    if not row: # empty line
      return []
    self.row_counter += 1
    try:
      if ':' in row[0]: # series label
        label,  row[0] = row[0].split(':')
        logger.debug("looking at row. %s => %s",  label,  row)
        self.series_labels.append(unicode(label,  'utf-8'))
    except AttributeError: # no cells in row
      pass
    return [cell(self.row_counter,  idx,  unicode(s, "utf-8")) for idx,  s in enumerate(row)]

  def __iter__(self):
    return self

class UnicodeCSVWriter:
  """
  A CSV writer which will write rows to CSV file "f",
  which is encoded in the given encoding. Lifted from the python docs.
  """

  def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
    # Redirect output to a queue
    self.queue = cStringIO.StringIO()
    self.writer = csv.writer(self.queue, dialect=dialect, **kwds)
    if not isinstance(f,  file):
      f = open(f,  "wb")
    self.stream = f
    self.encoder = codecs.getincrementalencoder(encoding)()

  def writerow(self, row,  label=None):
    if label is not None and len(row) > 0:
      row[0] = "%s:%s" % (label,  row[0])
    self.writer.writerow([u8(s) for s in row])
    # Fetch UTF-8 output from the queue ...
    data = self.queue.getvalue()
    data = data.decode("utf-8")
    # ... and reencode it into the target encoding
    data = self.encoder.encode(data)
    # write to the target stream
    self.stream.write(data)
    # empty queue
    self.queue.truncate(0)

def u8(s):
  if not isinstance(s,  basestring):
    return str(s)
  return s.encode('utf-8')

class cell:
  value = ""
  row = -1
  idx = -1
  def __init__(self,  row,  idx,  value):
    self.row = row
    self.idx = idx
    self.value = value
